package com.wn.ziroom.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wn.utils.CookieUtils;
import com.wn.utils.JwtUtils;
import com.wn.ziroom.entity.Cart;
import com.wn.ziroom.entity.CartItem;
import com.wn.ziroom.entity.Cities;
import com.wn.ziroom.entity.User;
import com.wn.ziroom.entity.vo.ProductionVo;
import com.wn.ziroom.mapper.CartItemMapper;
import com.wn.ziroom.mapper.CartMapper;
import com.wn.ziroom.mapper.CitiesMapper;
import com.wn.ziroom.mapper.ProductionVoMapper;
import com.wn.ziroom.service.CartItemService;
import com.wn.ziroom.service.CartService;
import com.wn.ziroom.service.CitiesService;
import com.wn.ziroom.utils.JsonUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author wangzhijia
 * @since 2023-02-23 02:27:54
 */
@Service
public class CartServiceImpl extends ServiceImpl<CartMapper, Cart> implements CartService {

    private CartMapper cartMapper;
    private CartItemMapper cartItemMapper;
    private CartItemService cartItemService;
    private ProductionVoMapper productionVoMapper;
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    public void setProductionVoMapper(ProductionVoMapper productionVoMapper) {
        this.productionVoMapper = productionVoMapper;
    }

    @Autowired
    public void setCartItemService(CartItemService cartItemService) {
        this.cartItemService = cartItemService;
    }

    @Autowired
    public void setCartItemMapper(CartItemMapper cartItemMapper) {
        this.cartItemMapper = cartItemMapper;
    }

    @Autowired
    public void setStringRedisTemplate(StringRedisTemplate stringRedisTemplate) {
        this.stringRedisTemplate = stringRedisTemplate;
    }

    @Autowired
    public void setCartMapper(CartMapper cartMapper) {
        this.cartMapper = cartMapper;
    }

    //---------------------------------------------------------------------------------------------------------------------
    @Override
    public int addProduction(Integer userId, ProductionVo production, Integer buyCount) {
        SetOperations<String, String> opsForSet = stringRedisTemplate.opsForSet();
        ListOperations<String, String> opsForList = stringRedisTemplate.opsForList();


        String key = "cart"+userId;
        String keyList = "cartList"+userId;

        List<String> range = opsForList.range(keyList, 0, -1);
        Long size = opsForList.size(keyList);
        if (size == 0){
            //-- 没有东西直接添加
            CartItem cartItem = new CartItem(production, buyCount);
            opsForList.leftPush(keyList,JsonUtils.toJsonStr(cartItem));
        }else {
            for (int i = 0; i < range.size(); i++) {
                CartItem cartItem = JsonUtils.toObject(range.get(i), CartItem.class);
                //book重写了equals 和 hashcode 可以直接用bookId???
                if (cartItem.getProductionVo().getProductionId() == production.getProductionId()){
                    cartItem.setBuyCount(cartItem.getBuyCount() + buyCount);
                    opsForList.set(keyList,i,JsonUtils.toJsonStr(cartItem));
                    return 1;
                }
            }
            CartItem cartItem2 = new CartItem(production, buyCount);
            opsForList.leftPush(keyList,JsonUtils.toJsonStr(cartItem2));
        }
        return 0;

//-------------------------------------------------------------------------------------------------------------------------
        /*
        if (stringRedisTemplate.hasKey(key)){


            Set<String> members = opsForSet.members(key);
            String[] target = new String[members.size()];
            int index = 0;

            //-- 标识是否有重复商品
            boolean flag = false;

            for (String member : members) {
                CartItem cartItem = JsonUtils.toObject(member, CartItem.class);
                //book重写了equals 和 hashcode 可以直接用bookId???
                if (cartItem.getProductionVo().getProductionId() == production.getProductionId()){
                    cartItem.setBuyCount(cartItem.getBuyCount() + buyCount);
                    flag = true;
                }
                target[index++] = JsonUtils.toJsonStr(cartItem);
            }

            *//*
            随机吐出个值(删除set中原来的值)
            while (opsForSet.size(key) != 0){
                opsForSet.pop(key);
            }
            *//*

            stringRedisTemplate.delete(key);
            opsForSet.add(key,target);

            //没有重复商品,直接set里新增
            if (!flag){
                CartItem cartItem = new CartItem(production, buyCount);
                opsForSet.add(key,JsonUtils.toJsonStr(cartItem));
            }

        }else {
            CartItem cartItem = new CartItem(production,buyCount);
            opsForSet.add(key, JsonUtils.toJsonStr(cartItem));

            //CartItem selectedCartItem = cartItemService.findByUserIdAndProId(userId,production.getProductionId(),buyCount);
        }
        return 0;*/
    }

    //-----------------------------------------------------------------------------------------------------------------------------
    @Override
    public List<CartItem> findCartByUserId(Integer userId) {

        ListOperations<String, String> opsForList = stringRedisTemplate.opsForList();

        String keyList = "cartList"+userId;

        List<String> range = opsForList.range(keyList, 0, -1);

        List<CartItem> cartItemList2 = new ArrayList<>();

        for (String s : range) {
            cartItemList2.add(JsonUtils.toObject(s, CartItem.class));
        }
        return cartItemList2;
        //==================================================================================================
        /*
        SetOperations<String, String> opsForSet = stringRedisTemplate.opsForSet();

        String key = "cart"+userId;

        List<CartItem> cartItemList = new ArrayList<>();

            Set<String> members = opsForSet.members(key);

            for (String member : members) {
                CartItem cartItem = JsonUtils.toObject(member, CartItem.class);
                cartItemList.add(cartItem);
            }
            return cartItemList;
            */
    }

    @Override
    public void deleteProduction(Integer userId, Integer productionId) {

        ListOperations<String, String> opsForList = stringRedisTemplate.opsForList();

        String keyList = "cartList"+userId;

        List<String> range = opsForList.range(keyList, 0, -1);

        List<String> temp = new ArrayList<>();

        for (int i = 0; i < range.size(); i++) {
            CartItem cartItem = JsonUtils.toObject(range.get(i), CartItem.class);
            if (cartItem.getProductionVo().getProductionId() == productionId){

            }else {
                temp.add(range.get(i));
            }
        }
        stringRedisTemplate.delete(keyList);
        for (String s : temp) {
            opsForList.leftPush(keyList,s);
        }

        //---------------------------------------------------------------------------
        /*SetOperations<String, String> opsForSet = stringRedisTemplate.opsForSet();

        String key = "cart"+userId;

        Set<String> members = opsForSet.members(key);

        String[] target = new String[members.size() - 1];
        int index = 0;

        for (String member : members) {
            CartItem cartItem = JsonUtils.toObject(member, CartItem.class);
            if (cartItem.getProductionVo().getProductionId() == productionId){

            }else {
                target[index++] = JsonUtils.toJsonStr(cartItem);
            }
        }
        stringRedisTemplate.delete(key);
        opsForSet.add(key,target);*/
    }

    @Override
    public void updateBuyCount(Integer userId, Integer buyCount,Integer productionId) {

        ListOperations<String, String> opsForList = stringRedisTemplate.opsForList();
        String keyList = "cartList"+userId;
        List<String> range = opsForList.range(keyList, 0, -1);
        List<String> temp = new ArrayList<>();
        for (int i = 0; i < range.size(); i++) {
            CartItem cartItem = JsonUtils.toObject(range.get(i), CartItem.class);
            if (cartItem.getProductionVo().getProductionId() == productionId){
                cartItem.setBuyCount(buyCount);
                temp.add(JsonUtils.toJsonStr(cartItem));
            }else {
                temp.add(JsonUtils.toJsonStr(cartItem));
            }
        }
        stringRedisTemplate.delete(keyList);
        for (String s : temp) {
            opsForList.leftPush(keyList,s);
        }

        //--------------------------------------------------------------------------------------------------------
       /* SetOperations<String, String> opsForSet = stringRedisTemplate.opsForSet();

        String key = "cart"+userId;

        Set<String> members = opsForSet.members(key);

        String[] target = new String[members.size()];
        int index = 0;

        for (String member : members) {
            CartItem cartItem = JsonUtils.toObject(member, CartItem.class);
            if (cartItem.getProductionVo().getProductionId() == productionId){
                cartItem.setBuyCount(buyCount);
            }
            target[index++] = JsonUtils.toJsonStr(cartItem);
        }
        stringRedisTemplate.delete(key);
        opsForSet.add(key,target);*/
    }

    @Override
    public List<CartItem> findCartByUserIdAndProIds(Integer userId, String[] productionIds) {

        ListOperations<String, String> opsForList = stringRedisTemplate.opsForList();

        String keyList = "cartList"+userId;

        List<String> range = opsForList.range(keyList, 0, -1);

        List<CartItem> temp = new ArrayList<>();

        for (String s : range) {
            CartItem cartItem = JsonUtils.toObject(s, CartItem.class);
            for (String productionId : productionIds) {
                if (cartItem.getProductionVo().getProductionId() == Integer.parseInt(productionId)){
                    temp.add(JsonUtils.toObject(s, CartItem.class));
                }
            }

        }
        return temp;
    }

    @Override
    public void deleteByProductionIds(String[] splitProductionId, Integer userId) {
        ListOperations<String, String> opsForList = stringRedisTemplate.opsForList();

        String keyList = "cartList"+userId;

        List<String> range = opsForList.range(keyList, 0, -1);

        List<String> temp = new ArrayList<>();

        for (String s : range) {
            boolean f = false;
            CartItem cartItem = JsonUtils.toObject(s, CartItem.class);
            for (String productionId : splitProductionId) {
                if (cartItem.getProductionVo().getProductionId() == Integer.parseInt(productionId)){
                    f = false;
                    break;
                }else {
                    f = true;
                }
            }
            if (f){
                temp.add(s);
            }
        }
        stringRedisTemplate.delete(keyList);
        for (String s : temp) {
            opsForList.leftPush(keyList,s);
        }

    }


}
